package com.mall.b2c.domain.goods;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.mall.b2c.domain.member.CommentDomain;
import com.mall.b2c.domain.member.MemberDomain;
import com.mall.b2c.domain.store.StoreGoodsDomain;
import com.mall.b2c.enums.PrescribeType;
import com.mall.b2c.util.SettingUtils;
import com.mall.common.domain.BaseEntity;
import com.mall.common.enums.MedicalInsuranceType;
import com.mall.common.util.UploadUtil;

import net.sf.json.JSONObject;

import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringUtils;
import org.hibernate.search.annotations.*;
import org.springframework.util.CollectionUtils;
import org.wltea.analyzer.lucene.IKAnalyzer;

import javax.persistence.*;

import java.math.BigDecimal;
import java.util.Date;
import java.util.Set;

@Entity
@Table(name = "b2c_goods")
@JsonIgnoreProperties(ignoreUnknown=true)
@Indexed(index = "goods")
@Analyzer(impl = IKAnalyzer.class)
public class GoodsDomain extends BaseEntity {

	/**
	 * 搜索框下拉搜索时商品全名去重，若分词则包含关键词只显示一条
	 * @return
	 */
	@Field(index = Index.UN_TOKENIZED, name = "goodsName", store = Store.YES)
	@Transient
	public String getGoodsName(){
		return name;
	}

	@Field(index = Index.UN_TOKENIZED, name = "code")
	private String code;// 商品编号 OK

	@Field(index = Index.TOKENIZED, name = "name")
	private String name;// 中文名OK

	@Field(index = Index.UN_TOKENIZED, name = "pyName", store = Store.YES)
	private String pyName;// 中文拼音OK

	@Field(index = Index.UN_TOKENIZED, name = "byName")
	private String byName;// 别名

	@Field(index = Index.UN_TOKENIZED, name = "isMarketable")
	private Boolean isMarketable;// 是否上架

	@Field(index = Index.UN_TOKENIZED, name = "keyword", store = Store.YES)
	private String keyword;// 搜索关键字

	@JsonIgnore
	@IndexedEmbedded
	private BrandDomain brand;// 品牌

	@JsonIgnore
	@IndexedEmbedded
	private GoodsCategoryDomain goodsCategory;// 商品分类


	private String enName;// 英文名

	private String tip;//提示
	private String barcode;// 条形码
	private String spec;// 规格 OK
	private String productionArea;// 产地 OK

	private String packingUnit;// 包装单位 OK
	private BigDecimal weight;//重量
	private BigDecimal marketPrice;// 建议零售价
	@Field(index = Index.UN_TOKENIZED, name = "price")
	private BigDecimal price;//销售价

	private Integer stock;// 库存

	private Integer priority;// 排序

	@Field(index = Index.UN_TOKENIZED, name = "sales")
	private Integer sales;// 购买次数
	private Integer views;// 商品浏览次数
	@Field(index = Index.UN_TOKENIZED, name = "cmts")
	private Integer cmts;//评论数
	private String cmtsJson;//好评，中评，差评JSON字符串 {hignOpinion:0, middleOpinion:0, lowOpinion:0}

	private String message;// 商品信息

	private Integer week_buy_count; // 周购买数
	private Date week_buy_date; // 周购买日期
	private Integer month_buy_count; // 月购买数
	private Date month_buy_date; // 月购买日期

	private String image_default; // 商品图片路径存储
	private String image_file; // 其他图片
	private String[] image_files;

	private Double integralRate; //积分兑换比率


	@JsonIgnore private Set<GoodsTagDomain> goodsTags; // 标签
	@JsonIgnore private Set<CommentDomain> comments;//评论
	@JsonIgnore private Set<StoreGoodsDomain> storeGoods;

	@Transient
	public JSONObject getGoodsInfo(MemberDomain member, String postfix){
		JSONObject jObj = new JSONObject();
		jObj.put("path", getPath());
		
		if(StringUtils.isBlank(image_default)) {
			image_default = "filePlugin:///img/default.jpg";
		}
		String image = UploadUtil.replacePath(image_default);
		jObj.put("image", UploadUtil.getImagePath(image, postfix));
		
		jObj.put("name", name);
		jObj.put("pyName", pyName != null ? pyName : "");
		jObj.put("spec", spec);
		jObj.put("marketPrice", marketPrice);
		if(brand != null){
			jObj.put("brandId", brand.getId());
			jObj.put("brandName", brand.getName());
		}
		return jObj;
	}
	
	@Transient
	public String getPath(){
		return SettingUtils.get().getUrlBuff(true).append("/goods/").append(getId()).append(".jhtml").toString();
	}
	
	@Transient
	public Boolean hasCollected(MemberDomain member) {
		if(member == null) {
			return false;
		}
		Set<GoodsDomain> favorites = member.getFavoriteGoods();
		if(!CollectionUtils.isEmpty(favorites)) {
			for(GoodsDomain favorite : favorites) {
				if(this.getId().equals(favorite.getId())) {
					return true;
				}
			}
		}
		return false;
	}
	
	@PrePersist
	public void prePersist() {
		if (ArrayUtils.isNotEmpty(image_files)) {
			StringBuilder sb = new StringBuilder();
			for (int i = 0; i < image_files.length; i++) {
				if (StringUtils.isNotBlank(image_files[i])
						&& !image_files[i].equals(",")) {
					sb.append(image_files[i]);
				}
				if (i < image_files.length - 1) {
					sb.append(",");
				}
			}
			setImage_file(sb.toString());
		}
		if(StringUtils.isBlank(cmtsJson)) {
			cmtsJson = "{hignOpinion:0, middleOpinion:0, lowOpinion:0}";
		}
		if(brand != null && brand.getId() == null) {
			brand = null;
		}
	}
	
	@Transient
	public Boolean hasStock() {
		return this.stock != null && this.stock > 0;
	}
	
	@Transient
	public String[] getImageList() {
		return StringUtils.isNotBlank(this.image_file) ? this.image_file.split(",") : null;
	}

	@Transient
	public String[] getImage_files() {
		return image_files;
	}

	public void setImage_files(String[] image_files) {
		this.image_files = image_files;
	}

	@Column(unique = true, nullable=false)
	public String getCode() {
		return code;
	}

	public void setCode(String code) {
		this.code = code;
	}

	@Column(nullable = false)
	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getEnName() {
		return enName;
	}

	public void setEnName(String enName) {
		this.enName = enName;
	}

	public String getPyName() {
		return pyName;
	}

	public void setPyName(String pyName) {
		this.pyName = pyName;
	}

	public String getByName() {
		return byName;
	}

	public void setByName(String byName) {
		this.byName = byName;
	}

	public String getTip() {
		return tip;
	}

	public void setTip(String tip) {
		this.tip = tip;
	}

	public String getBarcode() {
		return barcode;
	}

	public void setBarcode(String barcode) {
		this.barcode = barcode;
	}

	public String getSpec() {
		return spec;
	}

	public void setSpec(String spec) {
		this.spec = spec;
	}

	public String getProductionArea() {
		return productionArea;
	}

	public void setProductionArea(String productionArea) {
		this.productionArea = productionArea;
	}

	@ManyToOne(fetch = FetchType.LAZY)
	@JoinColumn(name = "brand_id")
	public BrandDomain getBrand() {
		return brand;
	}

	public void setBrand(BrandDomain brand) {
		this.brand = brand;
	}

	public String getPackingUnit() {
		return packingUnit;
	}

	public void setPackingUnit(String packingUnit) {
		this.packingUnit = packingUnit;
	}

	public BigDecimal getMarketPrice() {
		return marketPrice;
	}

	public void setMarketPrice(BigDecimal marketPrice) {
		this.marketPrice = marketPrice;
	}

	public Integer getStock() {
		return stock;
	}

	public void setStock(Integer stock) {
		this.stock = stock;
	}

	public Integer getPriority() {
		return priority;
	}

	public void setPriority(Integer priority) {
		this.priority = priority;
	}

	public String getKeyword() {
		return keyword;
	}

	public void setKeyword(String keyword) {
		this.keyword = keyword;
	}

	public Boolean getIsMarketable() {
		return isMarketable;
	}

	public void setIsMarketable(Boolean isMarketable) {
		this.isMarketable = isMarketable;
	}

	public Integer getSales() {
		return sales;
	}

	public void setSales(Integer sales) {
		this.sales = sales;
	}

	public Integer getViews() {
		return views;
	}

	public void setViews(Integer views) {
		this.views = views;
	}

	public Integer getCmts() {
		return cmts;
	}

	public void setCmts(Integer cmts) {
		this.cmts = cmts;
	}

	public String getCmtsJson() {
		return cmtsJson;
	}

	public void setCmtsJson(String cmtsJson) {
		this.cmtsJson = cmtsJson;
	}

	@ManyToOne(fetch = FetchType.LAZY)
	@JoinColumn(name = "goods_category_id")
	public GoodsCategoryDomain getGoodsCategory() {
		return goodsCategory;
	}

	public void setGoodsCategory(GoodsCategoryDomain goodsCategory) {
		this.goodsCategory = goodsCategory;
	}

	@Column(columnDefinition="varchar(2048)")
	public String getMessage() {
		return message;
	}

	public void setMessage(String message) {
		this.message = message;
	}

	public Integer getWeek_buy_count() {
		return week_buy_count;
	}

	public void setWeek_buy_count(Integer week_buy_count) {
		this.week_buy_count = week_buy_count;
	}

	public Date getWeek_buy_date() {
		return week_buy_date;
	}

	public void setWeek_buy_date(Date week_buy_date) {
		this.week_buy_date = week_buy_date;
	}

	public Integer getMonth_buy_count() {
		return month_buy_count;
	}

	public void setMonth_buy_count(Integer month_buy_count) {
		this.month_buy_count = month_buy_count;
	}

	public Date getMonth_buy_date() {
		return month_buy_date;
	}

	public void setMonth_buy_date(Date month_buy_date) {
		this.month_buy_date = month_buy_date;
	}

	public String getImage_default() {
		return image_default;
	}

	public void setImage_default(String image_default) {
		this.image_default = image_default;
	}

	@Column(columnDefinition="varchar(2000)")
	public String getImage_file() {
		return image_file;
	}

	public void setImage_file(String image_file) {
		this.image_file = image_file;
	}

	@OneToMany(fetch = FetchType.LAZY, mappedBy = "goods", cascade = { CascadeType.REMOVE })
	public Set<GoodsTagDomain> getGoodsTags() {
		return goodsTags;
	}

	public void setGoodsTags(Set<GoodsTagDomain> goodsTags) {
		this.goodsTags = goodsTags;
	}

	@OneToMany(fetch=FetchType.LAZY, mappedBy="goods", cascade = {CascadeType.REMOVE})
	public Set<CommentDomain> getComments() {
		return comments;
	}

	public void setComments(Set<CommentDomain> comments) {
		this.comments = comments;
	}


	@OneToMany(fetch = FetchType.LAZY, mappedBy = "goods", cascade = {CascadeType.REMOVE})
	public Set<StoreGoodsDomain> getStoreGoods() {
		return storeGoods;
	}

	public void setStoreGoods(Set<StoreGoodsDomain> storeGoods) {
		this.storeGoods = storeGoods;
	}

	public BigDecimal getPrice() {
		return price;
	}

	public void setPrice(BigDecimal price) {
		this.price = price;
	}

	public BigDecimal getWeight() {
		return weight;
	}

	public void setWeight(BigDecimal weight) {
		this.weight = weight;
	}

	@Column(columnDefinition="default 0")
	public Double getIntegralRate() {
		return integralRate;
	}

	public void setIntegralRate(Double integralRate) {
		this.integralRate = integralRate;
	}
}
